home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FishMarket 1.0
/
FishMarket v1.0.iso
/
fishies
/
176-200
/
disk_193
/
keymaped
/
source
/
kme_keymapio.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-05-06
|
16KB
|
507 lines
/*
* Key Map Editor ver 1.0
* Key Map IO
*
* by: Tim Friest
* on: January 1, 1989
*/
#include "KME_Includes.h"
#include "KME_Protos.h"
#include "KME_Defs.h"
#include "KME_Globals.h"
#define LongToByteArr(a, l) a[3] = (l & 0x000000FF); a[2] = ((l & 0x0000FF00)>>8); a[1] = ((l & 0x00FF0000)>>16); a[0] = ((l & 0xFF000000)>>24)
#define HUNK_HEADER 0x3F3
#define HUNK_CODE 0x3E9
#define HUNK_RELOC32 0x3EC
#define HUNK_END 0x3F2
struct RelocNode {
struct RelocNode *Next;
ULONG Offset;
};
struct KeyMap_Hunk {
ULONG Hunk;
ULONG Length;
struct KeyMapNode kh_KeyMapNode;
UBYTE kh_LoKeyMapTypes[0x40];
ULONG kh_LoKeyMap[0x40];
UBYTE kh_LoCapsable[0x08];
UBYTE kh_LoRepeatable[0x08];
UBYTE kh_HiKeyMapTypes[0x38];
ULONG kh_HiKeyMap[0x38];
UBYTE kh_HiCapsable[0x07];
UBYTE kh_HiRepeatable[0x07];
};
struct KeyMap_Hunk *CodeSegment;
struct RelocNode *RelocList = NULL;
extern struct KeyMapNode *ConvertKeyMap(struct KeyMapNode *);
extern ULONG MakeCodeSeg(struct KeyMapNode *, char *);
extern int InsertRelocList(ULONG);
/*
* KeyMapIO
*
* parameters: Filename - String pointer to filename
* Option - IO option (Read or Write)
*/
void KeyMapIO(filename, Option)
char *filename;
int Option;
{
if (Option == LOAD) {
if ((filename = ProcFileReq("Load")) != NULL) {
if (!ReadKeyMap(filename))
KeyMapNode = MakeNewKeyMap();
UpdateDisplay(GadgetList, KeyMapNode, TRUE);
}
else
if (!(CheckResource(RF_KeyMap)))
KeyMapNode = MakeNewKeyMap();
} else if (Option == SAVE) {
if ((filename = ProcFileReq("Save")) != NULL)
WriteKeyMap(filename);
}
}
/*
* ReadKeyMap
*
* parameter: Filename - Filename of KeyMap to read
* returns: Result - Success of operation (TRUE or FALSE)
*/
int ReadKeyMap(filename)
char *filename;
{
if (CheckResource(RF_KeyMap)) {
FreeKeyMap(KeyMapNode);
ClearResource(RF_KeyMap);
}
if ((KeyMapSegment = LoadSeg(filename)) == NULL) {
Write(Output(), "Error ReadKeyMap: LoadSeg failed\n", 33);
return(FALSE);
}
if ((KeyMapNode = ConvertKeyMap((struct KeyMapNode *)BADDR((KeyMapSegment+1)))) == NULL) {
Write(Output(), "Error ReadKeyMap: ConvertKeyMap Failed\n", 39);
return(FALSE);
}
UnLoadSeg(KeyMapSegment);
FlagResource(RF_KeyMap);
return(TRUE);
}
/*
* Convert Key Map Strings to freememable places
*
* parameters: KeyMapNode - Key Map Node structure
*
* returns: Success - TRUE or FALSE
*/
struct KeyMapNode *ConvertKeyMap(OldKeyMapNode)
struct KeyMapNode *OldKeyMapNode;
{
USHORT KeyCode;
struct HalfKeyMap *HalfKeyMap;
int length, maphalf;
UBYTE len, HeaderLen;
struct KeyMapNode *NewKeyMapNode;
UBYTE *old, *new;
if ((NewKeyMapNode = (struct KeyMapNode *)AllocMem((KeyNodeSize + KeyMapSize), MEMF_CLEAR)) == NULL) {
Write(Output(), "Memory Allocation failed, ConvertKeyMap:KeyMap\n", 47);
return(NULL);
}
memcpy((UBYTE *)NewKeyMapNode, (UBYTE *)OldKeyMapNode, KeyNodeSize);
new = ((UBYTE *)NewKeyMapNode) + KeyNodeSize;
memcpy(new, OldKeyMapNode->kn_KeyMap.km_LoKeyMapTypes, 0x40);
NewKeyMapNode->kn_KeyMap.km_LoKeyMapTypes = new;
new += 0x40;
memcpy(new, (UBYTE *)OldKeyMapNode->kn_KeyMap.km_LoKeyMap, (0x40*4));
NewKeyMapNode->kn_KeyMap.km_LoKeyMap = (long *)new;
new += (0x40 * 4);
memcpy(new, OldKeyMapNode->kn_KeyMap.km_LoCapsable, 0x08);
NewKeyMapNode->kn_KeyMap.km_LoCapsable = new;
new += 0x08;
memcpy(new, OldKeyMapNode->kn_KeyMap.km_LoRepeatable, 0x08);
NewKeyMapNode->kn_KeyMap.km_LoRepeatable = new;
new += 0x08;
memcpy(new, OldKeyMapNode->kn_KeyMap.km_HiKeyMapTypes, 0x38);
NewKeyMapNode->kn_KeyMap.km_HiKeyMapTypes = new;
new += 0x38;
memcpy(new, (UBYTE *)OldKeyMapNode->kn_KeyMap.km_HiKeyMap, (0x38*4));
NewKeyMapNode->kn_KeyMap.km_HiKeyMap = (long *)new;
new += (0x38 * 4);
memcpy(new, OldKeyMapNode->kn_KeyMap.km_HiCapsable, 0x07);
NewKeyMapNode->kn_KeyMap.km_HiCapsable = new;
new += 0x07;
memcpy(new, OldKeyMapNode->kn_KeyMap.km_HiRepeatable, 0x07);
NewKeyMapNode->kn_KeyMap.km_HiRepeatable = new;
HalfKeyMap = (struct HalfKeyMap *)&NewKeyMapNode->kn_KeyMap;
maphalf = 0;
KeyCode = 0x00;
while (maphalf < 2)
if (((maphalf == 0) && (KeyCode < 0x40)) || ((maphalf == 1) && (KeyCode < 0x38))) {
switch (HalfKeyMap->KeyMapTypes[KeyCode] & (KCF_STRING|KCF_DEAD|KCF_NOP)) {
case KCF_STRING:
len = StringKeyLength(HalfKeyMap, KeyCode, &HeaderLen);
if ((new = (UBYTE *)AllocMem(len, MEMF_CLEAR)) == NULL) {
Write(Output(), "Memory allocation failed, ConvertKeyMap:String\n", 47);
return(NULL);
}
CopyStringKey(HalfKeyMap, KeyCode, new, HeaderLen);
HalfKeyMap->KeyMap[KeyCode] = (ULONG)new;
break;
case KCF_DEAD:
len = DeadKeyLength(HalfKeyMap, KeyCode, &HeaderLen);
if ((new = (UBYTE *)AllocMem(len, MEMF_CLEAR)) == NULL) {
Write(Output(), "Memory allocation failed, ConvertKeyMap:Dead\n", 46);
return(NULL);
}
CopyDeadKey(HalfKeyMap, KeyCode, new, HeaderLen);
HalfKeyMap->KeyMap[KeyCode] = (ULONG)new;
} /* switch */
KeyCode += 1;
}
else {
KeyCode = 0x00;
HalfKeyMap = (struct HalfKeyMap *)&NewKeyMapNode->kn_KeyMap.km_HiKeyMapTypes;
maphalf += 1;
}
old = OldKeyMapNode->kn_Node.ln_Name;
length = strlen(old) + 1;
if ((new = (UBYTE *)AllocMem(length, MEMF_CLEAR)) == NULL) {
Write(Output(), "Memory Allocation Failed, ConvertKeyMap:NodeName\n", 49);
return(NULL);
}
strcpy(new, old);
NewKeyMapNode->kn_Node.ln_Name = (char *)new;
return(NewKeyMapNode);
}
/*
* Free Key Map
*
* parameter: KeyMapNode - Key Map Node to free
*/
void FreeKeyMap(FreeKeyMapNode)
struct KeyMapNode *FreeKeyMapNode;
{
UBYTE *buff;
UBYTE len, headerlen;
struct HalfKeyMap *HalfKeyMap;
USHORT KeyCode;
int maphalf, length;
if ((buff = FreeKeyMapNode->kn_Node.ln_Name) != NULL) {
length = strlen(buff) + 1;
FreeMem(buff, length);
}
HalfKeyMap = (struct HalfKeyMap *)&FreeKeyMapNode->kn_KeyMap.km_HiKeyMapTypes;
maphalf = 1;
KeyCode = 0x37;
while (maphalf >= 0) {
KeyCode -= 1;
switch (HalfKeyMap->KeyMapTypes[KeyCode] & (KCF_STRING|KCF_DEAD|KCF_NOP)) {
case KCF_STRING:
buff = (UBYTE *)HalfKeyMap->KeyMap[KeyCode];
len = StringKeyLength(HalfKeyMap, KeyCode, &headerlen);
FreeMem(buff, len);
break;
case KCF_DEAD:
buff = (UBYTE *)HalfKeyMap->KeyMap[KeyCode];
len = DeadKeyLength(HalfKeyMap, KeyCode, &headerlen);
FreeMem(buff, len);
} /* switch */
if (KeyCode == 0x00) {
KeyCode = 0x3F;
HalfKeyMap = (struct HalfKeyMap *)&FreeKeyMapNode->kn_KeyMap;
maphalf -= 1;
}
} /* while */
FreeMem((UBYTE *)FreeKeyMapNode, (KeyNodeSize + KeyMapSize));
ClearFlag(RF_KeyMap);
}
/*
* WriteKeyMap
*
* parameter: Filename - Filename of KeyMap to read
* returns: Result - Success of operation (TRUE or FALSE)
*/
int WriteKeyMap(filename)
char *filename;
{
BPTR File;
ULONG CodeLen, RelocLen;
struct RelocNode *temp, *next;
UBYTE bytes[4];
int status = TRUE;
if ((CodeLen = MakeCodeSeg(KeyMapNode, filename)) == NULL) {
Write(Output(), "HUNK_CODE Creation Error\n", 24);
goto EndWrite;
}
if ((File = Open(filename, MODE_NEWFILE)) == NULL)
return(FALSE);
/* Creating an executable HUNK */
LongToByteArr(bytes, HUNK_HEADER);
if (Write(File, bytes, 4) != 4) {
Write(Output(), "Write Error, Hunk_Header\n", 25);
status = FALSE;
goto EndWrite;
}
/* No libraries used */
LongToByteArr(bytes, 0);
if (Write(File, bytes, 4) != 4) {
Write(Output(), "Write Error, Hunk_Header libname\n", 34);
status = FALSE;
goto EndWrite;
}
/* Hunk table size */
LongToByteArr(bytes, 1);
if (Write(File, bytes, 4) != 4) {
Write(Output(), "Write Error, Hunk_Header table\n", 31);
status = FALSE;
goto EndWrite;
}
/* First hunk */
LongToByteArr(bytes, 0);
if (Write(File, bytes, 4) != 4) {
Write(Output(), "Write Error, Hunk_Header first hunk\n", 36);
status = FALSE;
goto EndWrite;
}
/* Last hunk */
LongToByteArr(bytes, 0);
if (Write(File, bytes, 4) != 4) {
Write(Output(), "Write Error, Hunk_Header last hunk\n", 35);
status = FALSE;
goto EndWrite;
}
/* write Hunk sizes (number of longwords) */
LongToByteArr(bytes, ((CodeLen>>2)-2));
if (Write(File, bytes, 4) != 4) {
Write(Output(), "Write Error, Hunk_Header sizes\n", 31);
status = FALSE;
goto EndWrite;
}
/* write HUNK_CODE */
if (Write(File, (UBYTE *)CodeSegment, CodeLen) != CodeLen) {
Write(Output(), "Write Error, HUNK_CODE\n", 22);
status = FALSE;
goto EndWrite;
}
/* write Hunk_Reloc32 */
LongToByteArr(bytes, HUNK_RELOC32);
if (Write(File, bytes, 4) != 4) {
Write(Output(), "Write Error, Hunk_Reloc32\n", 26);
status = FALSE;
goto EndWrite;
}
for (temp = RelocList, RelocLen = 0; temp; (temp = temp->Next), RelocLen++);
/* write hunk_reloc32 length (number of longwords) */
if (Write(File, (UBYTE *)&RelocLen, 4) != 4) {
Write(Output(), "Write Error, Hunk_Reloc32 Length\n", 33);
status = FALSE;
goto EndWrite;
}
/* write hunk_reloc32 hunk number effected */
LongToByteArr(bytes, 0);
if (Write(File, bytes, 4) != 4) {
Write(Output(), "Write Error, Hunk_Reloc32 hunk number\n", 38);
status = FALSE;
goto EndWrite;
}
/* write hunk_reloc32 offsets */
for (temp = RelocList; temp; temp = temp->Next)
if (Write(File, (UBYTE *)&temp->Offset, 4) != 4) {
Write(Output(), "Write Error, Hunk_Reloc32 offset\n", 33);
status = FALSE;
goto EndWrite;
}
/* write end Hunk_Reloc32 */
LongToByteArr(bytes, 0);
if (Write(File, bytes, 4) != 4) {
Write(Output(), "Write Error, Hunk_Reloc32 end\n", 30);
status = FALSE;
goto EndWrite;
}
/* write Hunk_End */
LongToByteArr(bytes, HUNK_END);
if (Write(File, bytes, 4) != 4) {
Write(Output(), "Write Error, Hunk_End\n", 22);
status = FALSE;
goto EndWrite;
}
EndWrite:
Close(File);
FreeMem((UBYTE *)CodeSegment, CodeLen);
for (temp = RelocList; temp; temp = next) {
next = temp->Next;
FreeMem((UBYTE *)temp, sizeof(struct RelocNode));
}
if (status) {
SetProtection(filename, 0x02);
ClearFlag(SF_Modified);
}
return(status);
}
/*
* Make Code Segment
*
* Convert KeyMap to a HUNK_CODE hunk
*
* parameter: KeyMapNode - Pointer to Key Map Node
* returns: LoadSeg - Pointer to LoadSeg
*/
ULONG MakeCodeSeg(KeyMapNode, filename)
struct KeyMapNode *KeyMapNode;
char *filename;
{
UBYTE *Segment;
struct KeyMap *KeyMap;
ULONG *NewKeyMap;
struct HalfKeyMap *HalfKeyMap, *NewHalfKeyMap;
USHORT KeyCode;
int maphalf;
ULONG SegmentLen, len, offset;
UBYTE headerlen;
len = sizeof(struct KeyMap_Hunk);
HalfKeyMap = (struct HalfKeyMap *)&KeyMapNode->kn_KeyMap;
maphalf = 0;
KeyCode = 0x00;
while (maphalf < 2)
if (((maphalf == 0) && (KeyCode < 0x40)) || ((maphalf == 1) && (KeyCode < 0x38))) {
switch (HalfKeyMap->KeyMapTypes[KeyCode] & (KCF_STRING|KCF_DEAD|KCF_NOP)) {
case KCF_STRING:
len += StringKeyLength(HalfKeyMap, KeyCode, &headerlen);
break;
case KCF_DEAD:
len += DeadKeyLength(HalfKeyMap, KeyCode, &headerlen);
} /* switch */
KeyCode += 1;
}
else {
KeyCode = 0x00;
HalfKeyMap = (struct HalfKeyMap *)&KeyMapNode->kn_KeyMap.km_HiKeyMapTypes;
maphalf += 1;
}
len += strlen(filename) + 1;
len = (len & 0x03)?((len & ~0x03)+4):len;
if ((CodeSegment = (struct KeyMap_Hunk *)AllocMem(len, MEMF_CLEAR)) == NULL) {
Write(Output(), "Memory Allocation Failed, MakeCodeSeg:CodeSegment\n", 50);
return(NULL);
}
SegmentLen = (len>>2) - 2;
CodeSegment->Hunk = HUNK_CODE;
CodeSegment->Length = SegmentLen;
Segment = (UBYTE *)&CodeSegment->kh_KeyMapNode;
offset = sizeof(struct KeyMap_Hunk) - 8;
memcpy(Segment, (UBYTE *)KeyMapNode, offset);
KeyMap = &CodeSegment->kh_KeyMapNode.kn_KeyMap;
KeyMap->km_LoKeyMapTypes = (UBYTE *)((ULONG)&CodeSegment->kh_LoKeyMapTypes - (ULONG)&CodeSegment->kh_KeyMapNode);
if (!InsertRelocList((ULONG)&KeyMap->km_LoKeyMapTypes - (ULONG)&CodeSegment->kh_KeyMapNode))
return(NULL);
KeyMap->km_LoKeyMap = (ULONG *)((ULONG)&CodeSegment->kh_LoKeyMap - (ULONG)&CodeSegment->kh_KeyMapNode);
if (!InsertRelocList((ULONG)&KeyMap->km_LoKeyMap - (ULONG)&CodeSegment->kh_KeyMapNode))
return(NULL);
KeyMap->km_LoCapsable = (UBYTE *)((ULONG)&CodeSegment->kh_LoCapsable - (ULONG)&CodeSegment->kh_KeyMapNode);
if (!InsertRelocList((ULONG)&KeyMap->km_LoCapsable - (ULONG)&CodeSegment->kh_KeyMapNode))
return(NULL);
KeyMap->km_LoRepeatable = (UBYTE *)((ULONG)&CodeSegment->kh_LoRepeatable - (ULONG)&CodeSegment->kh_KeyMapNode);
if (!InsertRelocList((ULONG)&KeyMap->km_LoRepeatable - (ULONG)&CodeSegment->kh_KeyMapNode))
return(NULL);
KeyMap->km_HiKeyMapTypes = (UBYTE *)((ULONG)&CodeSegment->kh_HiKeyMapTypes - (ULONG)&CodeSegment->kh_KeyMapNode);
if (!InsertRelocList((ULONG)&KeyMap->km_HiKeyMapTypes - (ULONG)&CodeSegment->kh_KeyMapNode))
return(NULL);
KeyMap->km_HiKeyMap = (ULONG *)((ULONG)&CodeSegment->kh_HiKeyMap - (ULONG)&CodeSegment->kh_KeyMapNode);
if (!InsertRelocList((ULONG)&KeyMap->km_HiKeyMap - (ULONG)&CodeSegment->kh_KeyMapNode))
return(NULL);
KeyMap->km_HiCapsable = (UBYTE *)((ULONG)&CodeSegment->kh_HiCapsable - (ULONG)&CodeSegment->kh_KeyMapNode);
if (!InsertRelocList((ULONG)&KeyMap->km_HiCapsable - (ULONG)&CodeSegment->kh_KeyMapNode))
return(NULL);
KeyMap->km_HiRepeatable = (UBYTE *)((ULONG)&CodeSegment->kh_HiRepeatable - (ULONG)&CodeSegment->kh_KeyMapNode);
if (!InsertRelocList((ULONG)&KeyMap->km_HiRepeatable - (ULONG)&CodeSegment->kh_KeyMapNode))
return(NULL);
HalfKeyMap = (struct HalfKeyMap *)&KeyMapNode->kn_KeyMap;
NewKeyMap = CodeSegment->kh_LoKeyMap;
NewHalfKeyMap = (struct HalfKeyMap *)&CodeSegment->kh_KeyMapNode.kn_KeyMap;
maphalf = 0;
KeyCode = 0x00;
while (maphalf < 2)
if (((maphalf == 0) && (KeyCode < 0x40)) || ((maphalf == 1) && (KeyCode < 0x38))) {
switch (HalfKeyMap->KeyMapTypes[KeyCode] & (KCF_STRING|KCF_DEAD|KCF_NOP)) {
case KCF_STRING:
len = StringKeyLength(HalfKeyMap, KeyCode, &headerlen);
len = CopyStringKey(HalfKeyMap, KeyCode, &Segment[offset], headerlen);
NewKeyMap[KeyCode] = offset;
if (!InsertRelocList((ULONG)&NewHalfKeyMap->KeyMap[KeyCode]))
return(NULL);
offset += len;
break;
case KCF_DEAD:
len = DeadKeyLength(HalfKeyMap, KeyCode, &headerlen);
len = CopyDeadKey(HalfKeyMap, KeyCode, &Segment[offset], headerlen);
NewKeyMap[KeyCode] = offset;
if (!InsertRelocList((ULONG)&NewHalfKeyMap->KeyMap[KeyCode]))
return(NULL);
offset += len;
} /* switch */
KeyCode += 1;
}
else {
KeyCode = 0x00;
HalfKeyMap = (struct HalfKeyMap *)&KeyMapNode->kn_KeyMap.km_HiKeyMapTypes;
NewKeyMap = CodeSegment->kh_HiKeyMap;
NewHalfKeyMap = (struct HalfKeyMap *)&CodeSegment->kh_KeyMapNode.kn_KeyMap.km_HiKeyMapTypes;
maphalf += 1;
}
len = strlen(filename) + 1;
memcpy(&Segment[offset], filename, len);
CodeSegment->kh_KeyMapNode.kn_Node.ln_Name = (UBYTE *)offset;
if (!InsertRelocList((ULONG)&CodeSegment->kh_KeyMapNode.kn_Node.ln_Name - (ULONG)Segment))
return(NULL);
return((SegmentLen+2)<<2);
}
/*
* Insert Reloc List
*
* parameter: Offset - offset of pointer
* return: Success - TRUE if success
*/
int InsertRelocList(offset)
ULONG offset;
{
struct RelocNode *new, *temp, *prev;
prev = NULL;
for (temp = RelocList; (temp != NULL) && (temp->Offset > offset); temp = temp->Next)
prev = temp;
if ((new = (struct RelocNode *)AllocMem(sizeof(struct RelocNode), MEMF_CLEAR)) == NULL) {
Write(Output(), "Memory Allocation Failed, InsertRelocList\n", 42);
return(FALSE);
}
new->Offset = offset;
new->Next = temp;
if (prev == NULL)
RelocList = new;
else
prev->Next = new;
return(TRUE);
}